﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace Web7.FilterProviders.FilterCriterion
{
    public class ControllerActionFilterCriteria : IFilterCriteria
    {
        private readonly List<ReflectedActionDescriptor> _methods = new List<ReflectedActionDescriptor>();

        public void AddMethod<T>(Expression<Func<T, object>> method)
        {
            MethodCallExpression methodCall = method.Body as MethodCallExpression;

            if (methodCall == null)
                throw new InvalidOperationException();

            _methods.Add(new ReflectedActionDescriptor(methodCall.Method, methodCall.Method.Name, new ReflectedControllerDescriptor(methodCall.Object.Type)));
        }

        #region IFilterCriteria Members

        public bool Match(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
        {
            ReflectedActionDescriptor reflectedDescriptor = actionDescriptor as ReflectedActionDescriptor;

            if (reflectedDescriptor != null)
                return _methods.Any(a => a.MethodInfo == reflectedDescriptor.MethodInfo);

            return _methods.Any(a => a.ControllerDescriptor.FindAction(controllerContext, actionDescriptor.ActionName) != null);
        }

        #endregion
    }
}
